using System.Security.Cryptography;
using System.Text;
using SheLife.Application.Interfaces;
using SheLife.Domain.Entities;
using SheLife.Domain.Interfaces;

namespace SheLife.Application.Services
{
    /// <summary>
    /// 用户服务实现
    /// </summary>
    public class UserService : IUserService
    {
        private readonly IUnitOfWork _unitOfWork;

        public UserService(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        /// <summary>
        /// 根据ID获取用户
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns>用户实体</returns>
        public async Task<User?> GetUserByIdAsync(Guid id)
        {
            return await _unitOfWork.UserRepository.GetByIdAsync(id);
        }

        /// <summary>
        /// 根据用户名获取用户
        /// </summary>
        /// <param name="username">用户名</param>
        /// <returns>用户实体</returns>
        public async Task<User?> GetUserByUsernameAsync(string username)
        {
            var users = await _unitOfWork.UserRepository.GetAllAsync();
            return users.FirstOrDefault(u => u.Username == username && !u.IsDeleted);
        }

        /// <summary>
        /// 根据邮箱获取用户
        /// </summary>
        /// <param name="email">邮箱</param>
        /// <returns>用户实体</returns>
        public async Task<User?> GetUserByEmailAsync(string email)
        {
            var users = await _unitOfWork.UserRepository.GetAllAsync();
            return users.FirstOrDefault(u => u.Email == email && !u.IsDeleted);
        }

        /// <summary>
        /// 创建用户
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="email">邮箱</param>
        /// <param name="password">密码</param>
        /// <returns>用户实体</returns>
        public async Task<User> CreateUserAsync(string username, string email, string password)
        {
            // 检查用户名是否已存在
            var existingUserByUsername = await GetUserByUsernameAsync(username);
            if (existingUserByUsername != null)
            {
                throw new ArgumentException("用户名已存在");
            }

            // 检查邮箱是否已存在
            var existingUserByEmail = await GetUserByEmailAsync(email);
            if (existingUserByEmail != null)
            {
                throw new ArgumentException("邮箱已被注册");
            }

            // 创建用户
            var passwordHash = HashPassword(password);
            var user = User.Create(username, email, passwordHash);

            await _unitOfWork.UserRepository.AddAsync(user);
            await _unitOfWork.SaveChangesAsync();

            return user;
        }

        /// <summary>
        /// 更新用户信息
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <param name="nickname">昵称</param>
        /// <param name="avatarUrl">头像URL</param>
        /// <param name="birthday">生日</param>
        /// <param name="lifeStage">生命周期阶段</param>
        /// <returns>用户实体</returns>
        public async Task<User?> UpdateUserProfileAsync(Guid id, string? nickname, string? avatarUrl, DateTime? birthday, string? lifeStage)
        {
            var user = await _unitOfWork.UserRepository.GetByIdAsync(id);
            if (user == null || user.IsDeleted)
            {
                return null;
            }

            user.UpdateProfile(nickname, avatarUrl, birthday, lifeStage);
            await _unitOfWork.UserRepository.UpdateAsync(user);
            await _unitOfWork.SaveChangesAsync();

            return user;
        }

        /// <summary>
        /// 更新用户密码
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <param name="currentPassword">当前密码</param>
        /// <param name="newPassword">新密码</param>
        /// <returns>是否成功</returns>
        public async Task<bool> UpdateUserPasswordAsync(Guid id, string currentPassword, string newPassword)
        {
            var user = await _unitOfWork.UserRepository.GetByIdAsync(id);
            if (user == null || user.IsDeleted)
            {
                return false;
            }

            // 验证当前密码
            if (!VerifyPassword(currentPassword, user.PasswordHash))
            {
                return false;
            }

            // 更新密码
            var newPasswordHash = HashPassword(newPassword);
            user.UpdatePassword(newPasswordHash);
            await _unitOfWork.UserRepository.UpdateAsync(user);
            await _unitOfWork.SaveChangesAsync();

            return true;
        }

        /// <summary>
        /// 验证用户邮箱
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns>是否成功</returns>
        public async Task<bool> VerifyUserEmailAsync(Guid id)
        {
            var user = await _unitOfWork.UserRepository.GetByIdAsync(id);
            if (user == null || user.IsDeleted)
            {
                return false;
            }

            user.VerifyEmail();
            await _unitOfWork.UserRepository.UpdateAsync(user);
            await _unitOfWork.SaveChangesAsync();

            return true;
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns>是否成功</returns>
        public async Task<bool> DeleteUserAsync(Guid id)
        {
            var user = await _unitOfWork.UserRepository.GetByIdAsync(id);
            if (user == null || user.IsDeleted)
            {
                return false;
            }

            await _unitOfWork.UserRepository.DeleteAsync(id);
            await _unitOfWork.SaveChangesAsync();

            return true;
        }

        /// <summary>
        /// 哈希密码
        /// </summary>
        /// <param name="password">明文密码</param>
        /// <returns>哈希后的密码</returns>
        private string HashPassword(string password)
        {
            using var sha256 = SHA256.Create();
            var hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
            return Convert.ToBase64String(hashedBytes);
        }

        /// <summary>
        /// 验证密码
        /// </summary>
        /// <param name="password">明文密码</param>
        /// <param name="passwordHash">密码哈希</param>
        /// <returns>是否匹配</returns>
        private bool VerifyPassword(string password, string passwordHash)
        {
            var computedHash = HashPassword(password);
            return computedHash == passwordHash;
        }
    }
}